// services/GitService.ts
import simpleGit, { SimpleGit, LogResult } from 'simple-git';
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);

import {
  GitCommit,
  CommitHistoryResult,
  CloneResult,
  ModifyCommitsResult,
  PushResult,
  CommitModificationResult
} from '../../types/git';

export class GitService {
  private repositories: Map<string, SimpleGit>;

  constructor() {
    this.repositories = new Map();
  }

  // 克隆仓库
  async cloneRepository(url: string, username: string, password: string, localPath: string): Promise<CloneResult> {
    try {
      // 构建带认证的 URL
      const authUrl = this.buildAuthUrl(url, username, password);

      const git: SimpleGit = simpleGit();
      await git.clone(authUrl, localPath);

      const repoGit: SimpleGit = simpleGit(localPath);
      this.repositories.set(localPath, repoGit);

      return { success: true, path: localPath };
    } catch (error) {
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Unknown error occurred during clone'
      };
    }
  }

  // 获取提交历史
  async getCommitHistory(repoPath: string, limit: number = 100): Promise<CommitHistoryResult> {
    try {
      let git: SimpleGit;

      if (this.repositories.has(repoPath)) {
        git = this.repositories.get(repoPath)!;
      } else {
        git = simpleGit(repoPath);
        this.repositories.set(repoPath, git);
      }

      const log: LogResult = await git.log({ maxCount: limit });
      const history: GitCommit[] = log.all.map((commit): GitCommit => ({
        hash: commit.hash,
        author: commit.author_name,
        email: commit.author_email,
        date: commit.date,
        message: commit.message,
        body: commit.body
      }));

      return {
        success: true,
        history
      };
    } catch (error) {
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Unknown error occurred while fetching commit history'
      };
    }
  }

  // 修改提交
  async modifyCommits(
    repoPath: string,
    commits: GitCommit[]): Promise<ModifyCommitsResult> {
    const results: CommitModificationResult[] = [];


    try {
      // 使用 filter-branch 修改提交
      await this.modifyWithFilterBranch(repoPath, commits);
      console.log('complete')
      // 标记所有提交为成功
      for (const commit of commits) {
        results.push({ hash: commit.hash, success: true });
      }

      // 删除备份分支
      //await execAsync(`git branch -D ${backupRef}`, { cwd: repoPath });

      return { success: true, results };
    } catch (error) {
      console.error(108, error)
      // 恢复原始状态
      //await this.restoreFromBackup(repoPath, backupRef);

      for (const commit of commits) {
        results.push({
          hash: commit.hash,
          success: false,
          error: error instanceof Error ? error.message : '使用 filter-branch 修改提交时发生错误'
        });
      }

      return { success: false, results };
    }

  }

  // 推送更改
  async pushChanges(repoPath: string, username: string, password: string): Promise<PushResult> {
    try {
      const git: SimpleGit | undefined = this.repositories.get(repoPath);

      if (!git) {
        return { success: false, error: 'Repository not found in cache' };
      }

      // 获取远程 URL
      let remoteUrl: string = '';
      try {
        // 尝试获取 origin 远程的 URL
        const result = await git.remote(['get-url', 'origin']);

        if (typeof result === 'string') {
          remoteUrl = result.trim()
        }
      } catch (error) {
        return {
          success: false,
          error: `无法获取远程仓库 URL: ${error instanceof Error ? error.message : '未知错误'}`
        };
      }
      // 构建带认证的 URL
      const authUrl: string = this.buildAuthUrl(remoteUrl, username, password);

      // 添加临时远程用于认证推送
      const tempRemoteName = 'temp-auth-remote';
      try {
        await git.addRemote(tempRemoteName, authUrl);

        // 强制推送到临时远程
        await git.push(['-f', tempRemoteName, 'HEAD:master']); // 假设推送到 master 分支

        return { success: true };
      } catch (error) {
        return {
          success: false,
          error: error instanceof Error ? error.message : '推送过程中发生未知错误'
        };
      } finally {
        // 清理：移除临时远程
        try {
          await git.removeRemote(tempRemoteName);
        } catch (cleanupError) {
          console.warn('清理临时远程时出错:', cleanupError);
        }
      }
    } catch (error) {
      return {
        success: false,
        error: error instanceof Error ? error.message : '推送过程中发生未知错误'
      };
    }
  }

  // 获取仓库实例
  getRepository(repoPath: string): SimpleGit | undefined {
    return this.repositories.get(repoPath);
  }

  // 移除仓库实例
  removeRepository(repoPath: string): boolean {
    return this.repositories.delete(repoPath);
  }

  // 获取所有缓存的仓库路径
  getCachedRepositories(): string[] {
    return Array.from(this.repositories.keys());
  }

  // 构建带认证的 URL
  private buildAuthUrl(url: string, username: string, password: string): string {
    if (url.includes(`://${username}:${password}@`)) {
      return url;
    }
    if (url.startsWith('https://')) {
      return url.replace('https://', `https://${username}:${password}@`);
    } else if (url.startsWith('http://')) {
      return url.replace('http://', `http://${username}:${password}@`);
    }
    return url;
  }

  // 使用 filter-branch 修改提交
  private async modifyWithFilterBranch(
    repoPath: string,
    commits: GitCommit[]
  ): Promise<void> {
    // 创建修改脚本
    const script = this.createModificationScript(commits);

    const cmd = `git filter-branch -f --env-filter "${script.envFilter}" master`;
    console.log(cmd);
    // 使用 filter-branch 应用修改
    await execAsync(
      cmd,
      { cwd: repoPath }
    );

    // 清理 filter-branch 创建的备份引用
    //await this.cleanupFilterBranchBackups(repoPath);


  }

  // 创建修改脚本
  private createModificationScript(
    commits: GitCommit[]
  ): { envFilter: string } {

    const cases = commits.map(commit => {
      return `"${commit.hash}")
  export GIT_AUTHOR_NAME='${commit.author}'
  export GIT_AUTHOR_EMAIL='${commit.email}'
  export GIT_COMMITTER_NAME='${commit.author}'
  export GIT_COMMITTER_EMAIL='${commit.email}'
  export GIT_AUTHOR_DATE="${commit.date}"
  export GIT_COMMITTER_DATE="${commit.date}"
  ;;`
    })
    const envFilter = `
case $GIT_COMMIT in
    ${cases.join('\n')}
esac`.replace(/\n\s?/g, ' ').trim();

    return { envFilter };
  }
}


// 单例模式导出
export const gitService = new GitService();
